package org.cashbook.IO.dataManager;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Map;

import org.cashbook.configuration.Constants;
import org.cashbook.core.objects.account.IAccount;
import org.cashbook.core.objects.category.ICategory;
import org.cashbook.core.objects.category.SubCategory;
import org.cashbook.core.objects.keyword.IKeyword;
import org.cashbook.core.objects.transaction.ITransaction;
import org.cashbook.core.objects.transaction.TransactionList;
import org.cashbook.entities.IUser;

public class DataManagerTXT extends AbstractDataManager {
	private Map<String, Object> data = new HashMap<String, Object>();

	@Override
	public void saveDataToDB() {
		logger.finer("Creating hashmap for saving data", this);
		data.put(ITransaction.class.getName(), transactionBuffer);
		data.put(ICategory.class.getName(), categoryBuffer);
		data.put(IKeyword.class.getName(), keywordBuffer);
		data.put(IAccount.class.getName(), accountBuffer);
		data.put(IUser.class.getName(), userBuffer);
		data.put(SubCategory.class.getName(), subCategoryBuffer);
		logger.finer("Hashmap for saving data created", this);
		try {
			logger.info("Writing data to database", this);
			FileOutputStream file = new FileOutputStream(Constants.dataManagerFilePath);
			ObjectOutputStream output = new ObjectOutputStream(file);
			output.writeObject(data);
			output.close();
			this.logger.info("Save successfull; Saved " + transactionBuffer.size() + " TransactionOverview(s), " + categoryBuffer.size() + " Categories, " + keywordBuffer.size() + " Keyword(s), " + accountBuffer.size() + " Account(s), " + userBuffer.size() + " User(s)", this);
		} catch (IOException e) {
			this.logger.severe("Save failed", this);
		}
	}

	@Override
	public String getDataManagerType() {
		return "Textfile database";
	}

	@SuppressWarnings("unchecked")
	@Override
	protected void loadDataFromDB() {
		try {
			logger.info("Loading data from database", this);
			FileInputStream file = new FileInputStream(Constants.dataManagerFilePath);
			ObjectInputStream input = new ObjectInputStream(file);
			data = (Map<String, Object>) input.readObject();
			input.close();
			logger.finer("Extracting data from loaded hashmap", this);
			transactionBuffer = (Map<String, TransactionList>) data.get(ITransaction.class.getName());
			categoryBuffer = (Map<String, ICategory>) data.get(ICategory.class.getName());
			keywordBuffer = (Map<String, IKeyword>) data.get(IKeyword.class.getName());
			accountBuffer = (Map<String, IAccount>) data.get(IAccount.class.getName());
			userBuffer = (Map<String, IUser>) data.get(IUser.class.getName());
			subCategoryBuffer = (Map<String, ICategory>) data.get(SubCategory.class.getName());
			logger.finer("Successfully extracted data from hashmap", this);
			logger.info("Load successfull; Loaded " + transactionBuffer.size() + " TransactionOverview(s), " + categoryBuffer.size() + " Categories, " + keywordBuffer.size() + " Keyword(s), " + accountBuffer.size() + " Account(s), " + userBuffer.size() + " User(s)", this);
		} catch (FileNotFoundException e){
			logger.warning("File does not exist, load failed. Starting with empty buffer", this);
		} catch (IOException e) {
			logger.severe("Could not read object information; Load failed", this);
		} catch (ClassNotFoundException e) {
			logger.severe("Could not read object information; Load failed", this);
		}
	}

}
